package com.sun.bridge.consistency.aop;

import com.sun.bridge.annotation.BridgeValue;
import com.sun.bridge.processor.init.cache.container.MirrorCacheHolder;
import com.sun.bridge.consistency.ThreadContext;
import com.sun.bridge.zookeeper.data.ConfigKeyNodeData;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Jay
 * @version v1.0
 * @description 切面
 * @date 2019-02-18 12:07
 */
@Aspect
@Slf4j
@Component
public class BridgeAspect {


    /**
     * 切点
     */
    @Pointcut(value = "execution(public * *(..))")
    public void point() {

    }

    /**
     * 拦截带注解的方法
     *
     * @param joinPoint
     * @param bridgeValue
     * @return
     * @throws Throwable
     */
    @Around(value = "point() && @annotation(bridgeValue)")
    public Object proceed(ProceedingJoinPoint joinPoint, BridgeValue bridgeValue) throws Throwable {
        try {
            String mirrorVersion = ThreadContext.getMirrorVersion();
            if (StringUtils.isEmpty(mirrorVersion)) {
                mirrorVersion = ThreadContext.setMirrorVersion(MirrorCacheHolder.getLatestMirrorCacheVersion());
            }
            log.debug("[Bridge]>>>>>>>>>>>>> 当前线程:[{}]持有的镜像版本号为:{}", Thread.currentThread().getName(), mirrorVersion);
            ConcurrentHashMap<String, ConfigKeyNodeData> repertory = MirrorCacheHolder.getMirrorCache(mirrorVersion);
            if (!CollectionUtils.isEmpty(repertory)) {
                String configKey = bridgeValue.key();
                ConfigKeyNodeData configKeyNodeData = repertory.get(configKey);
                if (configKeyNodeData != null && !StringUtils.isEmpty(configKeyNodeData.getValue())) {
                    return configKeyNodeData.getValue();
                }
            }
            // 返回原值
            return joinPoint.proceed();
        } catch (Throwable t) {
            log.error(t.getMessage());
            throw t;
        }
    }

}
